<?php
declare(strict_types=1);

namespace Service\PayService\Payer;

use Service\BaseService;
use Service\UserService\MnUserService;
use Service\ConfigureService\ChannelConfigService;
use Service\ChannelService\StoreConfigService;
use Service\VenderClient\PayCenterApi\HelipayApiClient;
use Service\Code\Normal;
use Service\MessageService\PayNotifyService;
use Service\ChannelService\ChannelWxService;
use App\Model\BbcModel\Order;
use Service\DeclareService\PayDeclareService;
use Service\PayService\CashPayService;
use App\Model\BbcModel\OfflinePayReceive;

class Helipay extends BaseService
{
    public $checktime = 200;
    
    
    /**
     * 扫码支付
     * @param int $cid
     * @param int $mn_sid
     * @param array $extra
     */
    public function scanPay(int $cid,int $mn_sid,int $mnid,array $param)
    {
        $store_type = $param['store_type'];
//        if( $store_type == MnUserService::TYPE_O2O ) {
//            $config = ChannelConfigService::instance()->getChannelConfig('helipay_pay', $cid);
//        }
//        elseif( $store_type == MnUserService::TYPE_QZ ) {
//            $config = StoreConfigService::instance()->getConfig('helipay_pay', $mn_sid);
//        }
        $config = StoreConfigService::instance()->getConfig('helipay_pay', $mn_sid);
        if(empty($config)) {
            return Normal::returnCode(Normal::FAIL,"合利宝支付未配置");
        }
        
        $config['cid']  = $cid;
        $config['mnid'] = 4;
        if( !empty($param['auth_code']) ) {
            if( substr($param['auth_code'], 0,2) >= 20 ) {
                $authcodetype   = 'ALIPAY';
                $auth_user_pay_type= CashPayService::AUTH_USER_PAY_ALIPAY;
            }else{
                $authcodetype   = 'WECHAT';
                $auth_user_pay_type= CashPayService::AUTH_USER_PAY_WEIXIN;
            }
        }
//        $path=request()->getRequestUri();   
//        $url=request()->url(); 
//        $callback_url=str_replace($path, '', $url);
        $uri=request()->getUri();   
        $callback_url=$uri->getScheme() . '://' . $uri->getHost();
        $uriport=$uri->getPort();
        if(!empty($uriport)&&!in_array((string)$uriport, ['80','443'])){
            $callback_url=$callback_url.':'.$uriport;
        }
        $noticeUrl = "{$callback_url}/cashpay/notify/helipay/{$param['order_id']}";
        $serverParam=request()->getServerParams();
        $order = [
            'order_sn'           => $param['out_trade_no'],//订单号
            'money'       => $param['total_fee'],//金额
            'notifyUrl'         => $noticeUrl,
            'auth_code'          => $param['auth_code'],
            'ip'            => $serverParam['remote_addr']??'',
            'goods_name'         => $param['body']
        ];
        //前置仓
        $payreport_data = [];
        if( $store_type == MnUserService::TYPE_QZ && $param['is_order'] == 1 ) {
            //合利宝暂不支持线下收单的实名验证
            $order['buyerIdcard']=$param['buyer']['idcard'];
            $order['buyerTruename']=$param['buyer']['truename'];
            $companyConfig = StoreConfigService::instance()->getConfig('e_company', $mn_sid);
            if(empty($companyConfig)) {
                return Normal::returnCode(Normal::FAIL,"电商平台未配置");
            }
            $payreport_data= [
                'cid'           => $cid,
                'company'       => $companyConfig,
                'payconfig'     => $config,
                'pay_type'      => 'helipay',
                'pay_serial'    => '',
                'pay_sn'        => $param['out_trade_no']
            ];
        }
        //调用支付接口
        $initalRequest = json_encode($order,JSON_UNESCAPED_UNICODE);
        $client = (new HelipayApiClient($config));
        $result_call = $client->orderCasherScanPay($order);
        if( $result_call['code'] != Normal::SUC ) {
            return $result_call;
        }
        $response = $result_call['data'];
        if(isset($response['rt2_retCode']) && $response['rt2_retCode'] =='0000' &&
           isset($response['rt13_orderStatus']) && $response['rt13_orderStatus']=='SUCCESS'
         ) 
        {
            if( $store_type == MnUserService::TYPE_QZ && $param['is_order'] == 1 ) {
                $payreport_data['pay_serial'] = $response['rt16_outTransactionOrderId'];
            }
            return Normal::returnCode(Normal::SUC,"处理成功",[
                'transaction_id'    => $response['rt16_outTransactionOrderId'],
                'initalRequest'     => $initalRequest,
                'initalResponse'    => json_encode($response,JSON_UNESCAPED_UNICODE),
                'auth_user_pay_type'=> $auth_user_pay_type,
                'payreport_data'    => $payreport_data,
                'pay_time'          => $response['rt24_orderCompleteDate']?strtotime($response['rt24_orderCompleteDate']):0
            ]);
        }else{
            $order['time']          = 0 ;
            $order['cid']           = $cid;
            $order['mn_sid']        = $mn_sid;
            $order['store_type']    = $param['store_type'];
            $order['initalRequest'] = $initalRequest;
            $order['auth_user_pay_type']=$auth_user_pay_type;
            $order['payreport_data']=$payreport_data;
            $order['is_order']      =$param['is_order'];
            return $this->checkCashOrderPay($order,$config);
        }
    }
    
    public function checkCashOrderPay(array $param = [],array $payconfig=[]) {
        sleep(5);
        $param['time'] += 5;
        $payreport_data=$param['payreport_data'];
        $body=[
            'order_sn'=>$param['order_sn']
        ];
        $client = (new HelipayApiClient($payconfig));
        $result_call = $client->orderPayQuery($body);
        if( $result_call['code'] != Normal::SUC ) {
            return $result_call;
        }
        $response = $result_call['data'];
        if(isset($response['rt2_retCode']) && $response['rt2_retCode'] =='0000' &&
           isset($response['rt7_orderStatus']) && $response['rt7_orderStatus']=='SUCCESS'
         ) 
        {
            if( $param['store_type'] == MnUserService::TYPE_QZ && $param['is_order'] == 1 ) {
                
                $payreport_data['pay_serial'] = $response['rt18_outTransactionOrderId'];
                //PayDeclareService::instance()->publishMsg($payreport_data);
            }
            return Normal::returnCode(Normal::SUC,"处理成功",[
                'transaction_id'    => $response['rt18_outTransactionOrderId'],
                'initalRequest'     => $param['initalRequest'],
                'initalResponse'    => json_encode($response,JSON_UNESCAPED_UNICODE),
                'auth_user_pay_type'=>$param['auth_user_pay_type'],
                'payreport_data'    =>$payreport_data,
                'pay_time'          => $response['rt13_orderCompleteDate']!=''?strtotime($response['rt13_orderCompleteDate']):time()
            ]);
        }
        
        if( isset($response['rt7_orderStatus']) && ($response['rt7_orderStatus'] =='FAIL' ||$response['rt7_orderStatus'] =='CLOSE'||$response['rt7_orderStatus'] =='CANCEL' )) {
            $msg='';
            if ($response['rt7_orderStatus'] =='FAIL'){ $msg='支付密码错误或余额不足';}
            if ($response['rt7_orderStatus'] =='CLOSE') {  $msg='请勿重复支付';}
            if ($response['rt7_orderStatus'] =='CANCEL') {  $msg='支付已超时，请重新下单支付';}
            return Normal::returnCode(Normal::FAIL,$msg);
        }
        
        if ( $param['time'] >= $this->checktime ) {
            return Normal::returnCode(Normal::FAIL,"交易超时,请重试,已重试40次!");
        }
        
        return $this->checkCashOrderPay($param,$payconfig);
        
    }
    
    public function scanPayRefund(int $cid,int $mn_sid,int $mnid,array $param){
        $store_type = $param['store_type'];
//        if( $store_type == MnUserService::TYPE_O2O ) {
//            $config = ChannelConfigService::instance()->getChannelConfig('helipay_pay', $cid);
//        }
//        elseif( $store_type == MnUserService::TYPE_QZ ) {
//            $config = StoreConfigService::instance()->getConfig('helipay_pay', $mn_sid);
//        }
        $config = StoreConfigService::instance()->getConfig('helipay_pay', $mn_sid);
        if(empty($config)) {
            return Normal::returnCode(Normal::FAIL,"合利宝支付未配置");
        }
        
//        $path=request()->getRequestUri();   
//        $url=request()->url(); 
//        $callback_url=str_replace($path, '', $url);
        $uri=request()->getUri();   
        $callback_url=$uri->getScheme() . '://' . $uri->getHost();
        $uriport=$uri->getPort();
        if(!empty($uriport)&&!in_array((string)$uriport, ['80','443'])){
            $callback_url=$callback_url.':'.$uriport;
        }
        $noticeUrl = "{$callback_url}/cashpay/notify/helipay/{$param['order_id']}";
        $order_data = [
            'refundOrderId' => (string)$param['out_refund_no'],//退款单号
            'orderId' =>(string)$param['out_trade_no'],//原订单号
            'money' => $param['refund_fee'],
            'notifyUrl' => $noticeUrl,
        ];
        $client = (new HelipayApiClient($config));
        $result_call = $client->orderPayRefund($order_data);
        if( $result_call['code'] != Normal::SUC ) {
            return $result_call;
        }
        $response = $result_call['data'];
        if( $response['rt2_retCode'] =='0000' ) {
                return Normal::returnCode(Normal::SUC,'退款成功',$response);
        }elseif($response['rt2_retCode']=='0075'||$response['rt2_retCode']=='0001'){
            $order_data['time']=0;
            return $this->checkReturnPay($order_data,$config);
        }else{
            return Normal::returnCode(Normal::FAIL,'退款失败:'.$response['rt3_retMsg'],$response);
        }
    }
    
    public function checkReturnPay(array $param = [],array $payconfig=[]) {
        sleep(5);
        $param['time'] += 5;
        $order=[
            'refundOrderId'=>$param['refundOrderId']
        ];
        
        //调用查询支付订单状态接口
        $client = (new HelipayApiClient($payconfig));
        $result_query = $client->orderPayRefundQuery($order);
        if( $result_query['code'] != Normal::SUC ) {
            return $result_query;
        }
        $response = $result_query['data'];
        if(isset($response['rt2_retCode']) && $response['rt2_retCode'] =='0000' &&
           isset($response['rt8_orderStatus']) && $response['rt8_orderStatus']=='SUCCESS'
         ){
            return Normal::returnCode(Normal::SUC,'退款成功',$response);
        }elseif(isset($response['rt8_orderStatus']) && ($response['rt8_orderStatus']=='FAIL'||$response['rt8_orderStatus']=='CLOSE')){
            $msg='';
            if ($response['rt8_orderStatus'] =='FAIL'){ $msg='交易失败';}
            if ($response['rt8_orderStatus'] =='CLOSE') {  $msg='交易被关闭';}
            return Normal::returnCode(Normal::FAIL,$msg,$response);
        }else{
            if($param['time']>=$this->checktime){
                return Normal::returnCode(Normal::FAIL,'超时失败',$response);
           }else{
                return $this->checkReturnPay($param,$payconfig);
           }
        }
        
        
    }
    
    /**
     * 收银异步通知,不做处理直接记录数据库,业务在发起时已经同步处理 
     * @param type $msg
     */
    public function cashNotify($msg) {
        $data= $msg;
        $datajson= json_encode($msg,JSON_UNESCAPED_UNICODE);
        $pay_rece_sn_pay=$data['rt3_systemSerial']??'';
        $pay_rece_sn_refund=$data['rt4_systemSerial']??'';
        $msg_pay=$data['rt4_status']??'';
        $msg_refund=$data['rt5_status']??'';
        OfflinePayReceive::instance()->add([
            'cd'=>time(),
            'cid'=>0,
            'ordersn'=>$data['rt2_orderId']??'',
            'pay_rece_sn'=>$pay_rece_sn_pay!=''?$pay_rece_sn_pay:$pay_rece_sn_refund,
            'msg'=>$msg_pay!=''?$msg_pay:$msg_refund,
            'content'=>$datajson
        ]);
    }
}
